require "Common/define"
require "Logic/Config"
require "Common/functions"

TeamHeroItem = {};
HelperFunc.SetUIEnv(TeamHeroItem)
local this = TeamHeroItem;

function TeamHeroItem.InitLocalData()
    this.linkColor = "#" .. G.dataTable["t_global"][tostring(185)]["f_string_value"];
    this.mainColor = "#" .. G.dataTable["t_global"][tostring(237)]["f_string_value"];
    this.gameObject = nil;
    this.transform = nil;
    this.LuaBehaviour = nil;

    this.drawWrapper = nil;
    this.imgIcon = nil;
    this.imgBase = nil;
    this.txtLevel = nil;
    this.txtStarLevel = nil;
    this.txtAttack = nil;
    this.controller = nil;
    this.imgIcons = { {}, {} };
    this.txtLevels = { {}, {} };
    this.txtLvS = { {}, {} };
    this.txtProfession = { {}, {} };
    this.txtDetailTexts = { {}, {} };
    this.titleItem = { {}, {} };
    this.occuIcon = nil;
    this.Roles1 = {}
    this.Roles2 = {}
    this.indexCount = 1
    this.drawWrappers1 = {}
    this.drawWrappers2 = {}
    this.titleItem = { {}, {} };
end

this.InitLocalData()

local roleScale = { 0.94, 0.98, 0.93, 0.96, 1, 0.95 }
function TeamHeroItem.Init()
    local name, packageName = getUIName(PanelNames.TeamHeroItem);
    panelMgr:ShowUI(name, packageName, this.onCreate, Config.useLocalUI);
end

function TeamHeroItem.onCreate(obj)
    --obj:SetActive(false);
end

function TeamHeroItem.Destroy()
    this.InitLocalData()
end

function TeamHeroItem.initData(obj, data, idx, titleType, func, fightType, isShowDebris, idx_count, formation_type, self)
    gameObject = obj;
    local controller = obj:GetController("state");
    data.teamIndex = data.teamIndex or 1
    imgIcons[data.teamIndex][idx] = obj:GetChild("ModelPos");
    local title = obj:GetChild("title");
    titleItem[data.teamIndex][idx] = title;
    --imgBase = obj:GetChild("Image");l
    obj.data = data;
    obj.data.teamIdx = idx;
    txtLevels[data.teamIndex][idx] = title:GetChild("level");
    txtLvS[data.teamIndex][idx] = title:GetChild("LV");
    txtProfession[data.teamIndex][idx] = title:GetChild("outplacement");
    local titleController = title:GetController("Detail");
    local name = title:GetChild("name")
    local nameCtrl = title:GetController("friendName")

    local text = obj:GetChild("HeroSubtext");

    --txtStarLevel = obj:GetChild("starLevel");
    --txtAttack = obj:GetChild("Text");
    --occuIcon = obj:GetChild("icon");s

    --controller.selectedIndex = 1;
    this.updateDebris(obj, data, isShowDebris)
    local isEmpty = true;
    if data ~= nil and data["partnerId"] ~= nil then
        isEmpty = false;
    end
    if data["partnerModelId"] == 0 then
        isEmpty = true;
    end
    if func then
        local posInfo = { idx = idx, teamId = data.teamIndex, isEmpty = isEmpty, modelId = data["partnerModelId"] }
        func(posInfo, self);
    end

    if data ~= nil and data["partnerId"] ~= nil and data["partnerModelId"] ~= 0 then
        local url = HeroManager.GetHeroDrawingRolePath(data["partnerModelId"])
        --string.format("Model/Role/h%03d",data["partnerModelId"])
        local name = nil;
        if data.teamIndex == 1 then
            name = Roles1[idx] and Roles1[idx].name or nil;
            local useSkinId = logicMgr.SkinManager.getHeroSkinId(data["partnerModelId"])
            if data.skinId then
                useSkinId = data.skinId;
            end
            --自己的英雄要加皮肤
            url = HeroManager.GetHeroDrawingRolePath(data["partnerModelId"], nil, useSkinId);
        else
            name = Roles2[idx] and Roles2[idx].name or nil;
            if data.skinId and data.skinId > 0 then
                url = logicMgr.SkinManager.GetHeroModelPathBySkinId(data.skinId);
            end
        end
        if controller.selectedIndex == 1 and url ~= name then
            controller.selectedIndex = 0;
        end
        local cfg = logicMgr.TrialsManager.GetBossConfigById(data["partnerId"]);
        if fightType == EnumConst.FightTypeConst.SoloChaosTest then
            cfg = tostring(data["partnerId"]) == tostring(logicMgr.SoloChaosTestManager.getBossId());
        end
        local scaleIdx = idx % 5;
        if scaleIdx == 0 then
            scaleIdx = 5;
        end
        local scale = roleScale[scaleIdx];
        if cfg or (formation_type == EnumConst.FormationType.SoloChaosTest and data.teamIndex == 2) then
            scale = FightManager.bossScale;
        end
        if titleController then
            --if titleType == 0 then
            --this.updateTitle(obj, data, 1);
            this.updateTitle(nil, data, titleType, idx, fightType, formation_type);


            --else
            --    --this.updateTitle(obj, data, 0);
            --    this.updateTitle(obj, data, titleType);
            --end
        end
        titleItem[data.teamIndex][idx].visible = true;

        local heroPosCfg = decodeJsonStrToTabel(G.dataTable["t_hero"][tostring(data["partnerModelId"])]["f_fightTeamPos"]);
        --occuIcon.url = "ui://ICONAtlas/New_occupation_" .. data["type"];
        --imgIcon.url = "ui://HalfHeadAtlas/hero_halfhead_" .. data["partnerModelId"];

        titleItem[data.teamIndex][idx].x = -12 + scale * (heroPosCfg[1]);
        titleItem[data.teamIndex][idx].y = -130 + scale * (heroPosCfg[2]);
        if url ~= name then
            resMgr:LoadModelPrefab(url, function(go)
                local Role = nil
                if data.teamIndex == 1 then
                    Role = Roles1[idx]
                    drawWrapper = drawWrappers1[idx]
                else
                    Role = Roles2[idx]
                    drawWrapper = drawWrappers2[idx]
                end
                if drawWrapper == nil then
                    drawWrapper = GoWrapper.New()
                    if data.teamIndex == 1 then
                        drawWrappers1[idx] = drawWrapper
                    else
                        drawWrappers2[idx] = drawWrapper
                    end
                end

                if Role ~= nil and not HelperFunc.IsNull(Role.go) then
                    destroyImmediate(Role.go)
                    Role = nil
                end
                Role = {}
                local RoleGO = newObject(go)
                Role.go = RoleGO
                Role.name = url
                RoleGO:SetActive(true)
                RoleGO:AddComponent(TCanvas)
                RoleGO:AddComponent(TChangeSortingOrder)
                RoleGO.name = url
                local aniObj = Util.Lua_FindGameObject(RoleGO, "Animation") --RoleGO.transform:Find("Animation").gameObject;
                local shadow = Util.Lua_FindGameObject(RoleGO, "shadow") --RoleGO.transform:Find("shadow").gameObject
                shadow:SetActive(false)
                Util.PlayAction(aniObj, "fidle", true, 4);
                --local roleCfgId = logicMgr.HeroManager.GetHeroConfigbyModelId(data["partnerModelId"]) .f_HeroModel
                --local skinName = (G.dataTable["t_roleconfig"][roleCfgId] or {}).skin;
                --if skinName ~= nil and skinName ~= '' then
                --    Util.SetSkin(aniObj, skinName);
                --end
                logicMgr.EquipManager.setWeaponSkin(aniObj, data["partnerModelId"], data.teamIndex == 1, data.weaponRank);

                drawWrapper:SetWrapTarget(RoleGO, true)
                Util.Lua_SetLocalPositionXYZ(RoleGO.transform, 0, 0, 0);
                Util.Lua_GetLocalPositionXYZ(aniObj.transform, 0, 0, 0);
                Util.Lua_SetLocalRotationXYZ(aniObj.transform, 0, 0, 0);
                local scaleIdx = idx % 5;
                if scaleIdx == 0 then
                    scaleIdx = 5;
                end
                if imgIcons[data.teamIndex][idx] ~= nil then
                    imgIcons[data.teamIndex][idx]:SetNativeObject(drawWrapper)
                    if (data.teamIndex == 2) then
                        Roles2[idx] = Role
                        local cfg = logicMgr.TrialsManager.GetBossConfigById(data["partnerId"]);
                        if fightType == EnumConst.FightTypeConst.SoloChaosTest then
                            cfg = tostring(data["partnerId"]) == tostring(logicMgr.SoloChaosTestManager.getNowBossId());
                        end
                        if cfg ~= nil then
                            Util.Lua_SetLocalScaleXYZ(RoleGO.transform, -117, 117, 1);
                        else
                            Util.Lua_SetLocalScaleXYZ(RoleGO.transform, -roleScale[scaleIdx] * 90, roleScale[scaleIdx] * 90, 1);
                        end
                    else
                        data.teamIndex = 1;
                        Roles1[idx] = Role
                        Util.Lua_SetLocalScaleXYZ(RoleGO.transform, roleScale[scaleIdx] * 90, roleScale[scaleIdx] * 90, 1);
                    end
                else
                    if Role.go then
                        destroyImmediate(Role.go);
                        Role.go = nil;
                    end
                end
                controller.selectedIndex = 0;
            end)
            titleItem[data.teamIndex][idx].visible = true;

        else
            controller.selectedIndex = 0;
        end

        --if data["state"] ~= nil then
        --    if ZZMathBit.andOp(data["state"], EnumConst.HeroHeadStateEnum.BATTLE) > 0 then
        --        --imgBase.gameObject:SetActive(true);
        --        --txtAttribute.gameObject:SetActive(true);
        --    end
        --    if ZZMathBit.andOp(data["state"], EnumConst.HeroHeadStateEnum.ASSIST) > 0 then
        --        --imgBase.gameObject:SetActive(false);
        --        --txtAttribute.gameObject:SetActive(false);
        --    end
        --end
        local level, inLink = logicMgr.HeroManager.getHeroShowLevelByPartnerId(data.partnerId);
        if inLink == 2 then
            txtLevels[data.teamIndex][idx].text = string.TextColor(string.format(getLanguage("Level"), level), logicMgr.HeroManager.lvColors[2]);
        elseif inLink == 1 then
            txtLevels[data.teamIndex][idx].text = string.TextColor(string.format(getLanguage("Level"), level), logicMgr.HeroManager.lvColors[1]);
        elseif inLink == 3 then
            txtLevels[data.teamIndex][idx].text = string.TextColor(string.format(getLanguage("Level"), level), logicMgr.HeroManager.lvColors[3]);
        elseif cfg then
            if fightType == EnumConst.FightTypeConst.TRIAL then
                txtLevels[data.teamIndex][idx].text = string.format(getLanguage("Level"), logicMgr.TrialsManager.loadTrialsLevel() .. '');
            else
                txtLevels[data.teamIndex][idx].text = string.format(getLanguage("Level"), "???");
            end
        else
            txtLevels[data.teamIndex][idx].text = string.format(getLanguage("Level"), data["level"]);
        end
        if fightType == EnumConst.FightTypeConst.RankBattle then
            txtLevels[data.teamIndex][idx].text = string.format(getLanguage("Level"), 300)
        elseif fightType == EnumConst.FightTypeConst.DarkStreet then
            txtLevels[data.teamIndex][idx].text = string.format(getLanguage("Level"), dataTable.getGlobalInt(398))
        elseif fightType == EnumConst.FightTypeConst.ARENA then
            if formation_type ~= nil then
                if formation_type == EnumConst.FormationType.TeamCrossArenaDef
                        or formation_type == EnumConst.FormationType.TeamCrossArenaAtk then
                    txtLevels[data.teamIndex][idx].text = string.format(getLanguage("Level"), dataTable.getGlobalInt(491) or 300)
                end
            end
        end

        --if data["star"] then
        --    txtStarLevel.text = data["star"] / 10000;
        --else
        --    txtStarLevel.text = ""
        --end
        --txtAttack.text = ;

    else
        controller.selectedIndex = 1
        idx_count = idx_count or 6
        -- if fightType == EnumConst.FightTypeConst.ARENA or fightType == EnumConst.FightTypeConst.ARENARECORD then
        --     if idx==idx_count then
        --         obj:GetChild("tibu").text = ""
        --     elseif idx == 6 then
        --         obj:GetChild("tibu").text = ""
        --     end
        -- else
        local txt_tibu = obj:GetChild("tibu")
        if txt_tibu ~= nil then
            if idx == idx_count then
                txt_tibu.text = getLanguage("StageFunctionText9001")
            else
                txt_tibu.text = ""
            end
        end
        -- end
        titleItem[data.teamIndex][idx].visible = false;

        if idx == idx_count and fightType ~= EnumConst.FightTypeConst.GuildBoss then
            obj:GetChild("tibu").visible = true;
        end
    end
    if data.name or data.masterName then
        name.UBBEnabled = true
        name.text = data.name or data.masterName;
        nameCtrl.selectedIndex = 1
    else
        nameCtrl.selectedIndex = 0
    end
end

function TeamHeroItem.updateTitle(obj, data, type, idx, fightType, formation_type)
    if data ~= nil and data["partnerId"] ~= nil then
        local title = nil;
        if obj ~= nil then
            title = obj;
        else
            title = titleItem[data.teamIndex][idx];
        end
        local titleController = title:GetController("Detail");
        titleController.selectedIndex = type;
        local text = title:GetChild("HeroSubtext");
        local levelText = title:GetChild("level");
        levelText.text = string.format(getLanguage("Level"), data["level"])

        local decStr = ""
        if data and data["partnerModelId"] and data["partnerModelId"] ~= 0 then
            decStr = getLanguage(G.dataTable["t_hero"][tostring(data["partnerModelId"])].f_HeroSubtext);
        end
        local txtProfession = title:GetChild("outplacement");
        text.text = decStr;
        if txtProfession ~= nil and data.type then
            txtProfession.url = EnumConst.AtlasPath.ICONAtlas .. EnumConst.HeroTypeIcon[data.type];
        end
        if data.partnerId and data.partnerId ~= 0 then
            local level, inLink = logicMgr.HeroManager.getHeroShowLevelByPartnerId(data.partnerId);
            levelText.text = string.TextColor(string.format(getLanguage("Level"), level),logicMgr.HeroManager.lvColors[inLink]);
        end
        if fightType == EnumConst.FightTypeConst.RankBattle then
            levelText.text = string.format(getLanguage("Level"), 350)
        elseif fightType == EnumConst.FightTypeConst.DarkStreet then
            levelText.text = string.format(getLanguage("Level"), dataTable.getGlobalInt(398))
        elseif fightType == EnumConst.FightTypeConst.ARENA then
            if formation_type ~= nil then
                if formation_type == EnumConst.FormationType.TeamCrossArenaDef
                        or formation_type == EnumConst.FormationType.TeamCrossArenaAtk then
                    levelText.text = string.format(getLanguage("Level"), dataTable.getGlobalInt(491) or 300)
                end
            end
        end

        local name = title:GetChild("name")
        local nameCtrl = title:GetController("friendName")
        if data.name or data.masterName then
            name.UBBEnabled = true
            name.text = data.name or data.masterName;
            nameCtrl.selectedIndex = 1
        else
            nameCtrl.selectedIndex = 0
        end
    end
end

function TeamHeroItem.updateDebris(obj, data, type)
    local controller = obj:GetController("showDebris");
    if not controller then
        return ;
    end
    local itemId = StrangeFragmentManager.GetCurrentEquipFragment(data.partnerId);
    local item = CtrlManager.GetCtrl(PanelNames.Item);

    if itemId then
        controller.selectedIndex = type and 1 or 0;
        if type then
            local itemBtn = obj:GetChild("debris");
            item.initData(itemBtn, itemId, 1, false, nil, data.partnerId);
            itemBtn.onClick:Clear();
        end
    else
        controller.selectedIndex = 0
    end
end

function TeamHeroItem.CacheHeros()
    for key, value in pairs(Roles1) do
        --[[
        local shadow = Util.Lua_FindGameObject(value.go, "shadow")--value.transform:Find("shadow").gameObject;
        if shadow ~= nil then
            shadow:SetActive(true);
        else
            local role_name = value and value.go and value.go.name or "shadow" 
            logError("shadow is nil name:"..role_name)
        end
        value.go.transform:SetParent(panelMgr.BattleMain.transform)
        BattleSceneCacheResouce:AddCacheObj(value.name, value.go)
        ]]

    end
    for key, value in pairs(Roles2) do
        --[[
        local shadow = Util.Lua_FindGameObject(value.go, "shadow") --value.transform:Find("shadow").gameObject;
        if shadow ~= nil then
            shadow:SetActive(true);
        else
            local role_name = value and value.go and value.go.name or "shadow" 
            logError("shadow is nil name:"..role_name)
        end
        value.go.transform:SetParent(panelMgr.BattleMain.transform)
        BattleSceneCacheResouce:AddCacheObj(value.name, value.go)
        ]]
    end

    for k, v in pairs(Roles1) do
        if not HelperFunc.IsNull(v.go) then
            destroyImmediate(v.go);
        end
        v.go = nil
        v = nil
    end
    table.clear(Roles1);
    for k, v in pairs(Roles2) do
        if not HelperFunc.IsNull(v.go) then
            destroyImmediate(v.go);
        end
        v.go = nil
        v = nil

    end
    table.clear(Roles2);

    if drawWrappers1 then
        for key, value in pairs(drawWrappers1) do
            value:SetWrapTarget(nil, false)
        end
    end
    if drawWrappers2 then
        for key, value in pairs(drawWrappers2) do
            value:SetWrapTarget(nil, false)
        end
    end
end

function TeamHeroItem.updateTitlePos(obj, data, idx, fightType, idx_count)
    local helpManText = obj:GetChild("tibu");
    --idx_count = idx_count or 6
    if idx == idx_count and helpManText then
        helpManText.visible = false;
    end
    --if data["partnerModelId"] == nil then
    --    return ;
    --end
    --local heroPosCfg = decodeJsonStrToTabel(G.dataTable["t_hero"][tostring(data["partnerModelId"])]["f_fightTeamPos"]);
    --local cfg = logicMgr.TrialsManager.GetBossConfigById(data["partnerId"]);
    --
    --local scaleIdx = idx % 5;
    --if scaleIdx == 0 then
    --    scaleIdx = 5;
    --end
    --local scale = roleScale[scaleIdx];
    --if cfg ~= nil or (formation_type == EnumConst.FormationType.SoloChaosTest and data.teamIndex == 2) then
    --    scale = FightManager.bossScale;
    --end
    --local pos = obj:GetChild("title");
    --titleItem[data.teamIndex][idx].x = (obj.position.x) + scale * (pos.x + heroPosCfg[1]);
    --titleItem[data.teamIndex][idx].y = (obj.position.y) + scale * (pos.y + heroPosCfg[2]);
end

function TeamHeroItem.onClear()
    for k, v in pairs(Roles1) do
        destroyImmediate(v.go);
        v.go = nil
        v = nil
    end
    table.clear(Roles1);
    for k, v in pairs(Roles2) do
        destroyImmediate(v.go);
        v.go = nil
        v = nil
    end
    table.clear(Roles2);

end

return TeamHeroItem;